using System;
using System.Data;
using ILMXFrameWork.XMA;
using Microsoft.MetadirectoryServices;

namespace ILMXFrameWork.XMA.SQL
{
 /// <summary>
 /// The GenerateFullImportFile class gathers all of the parameters and 
 /// kicks off the process of generating a Full Import.txt ldif file from a SQL Data Source.
 /// </summary>
    /*Copyright (c) 2009, Joseph Stepongzi
   All rights reserved.
   Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
   * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
   * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
   * Neither the name of Joseph Stepongzi nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
    */
 public class GenerateFullImportFile
	{
        // variables
        private string baseQuery;
        private string multiValueQuery = "";
        private string multiValueAttributeColumn = "";
        private string multiValueValueColumn = "";  
        private string server;
        private string user;
        private string pswd;
        private string fullImportFile;
        private string objectClassAttribute;
        private string objectClassValue;
        private string db;
        private System.Text.Encoding encoding = System.Text.Encoding.UTF8;


        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="server">The name of the sql server to connect to.</param>
        /// <param name="user">The user name to connect to the sql server.</param>
        /// <param name="pswd">The password to connect to the sql server.</param>
        /// <param name="configParameters">The collection of configuration parameters passed from the ma configuration.</param>
        /// <param name="traceLog">The traceLog object that decides whether traces should be logged to the trace file.</param>

     public GenerateFullImportFile(string server, string user, string pswd, ConfigParameterCollection configParameters, ref ILMXFrameWork.XMA.Trace.TraceLog traceLog, TypeDescriptionCollection types)
		{
			this.server = server;
			this.user = user;
			this.pswd = pswd;

            if (traceLog.TraceEnabled())
            {
                traceLog.WriteLine("GenerateFullImportFile Started: " + DateTime.Now.ToString());
                traceLog.WriteLine("Parameter: Server Value: " + server + " " + DateTime.Now.ToString());
                traceLog.WriteLine("Parameter: User Value: " + user + " " + DateTime.Now.ToString());
            }
            // Cehck if there are any configuration parameters specified in the ma configuration.
			if (configParameters == null)
			{
				throw new UnexpectedDataException("Missing Configuration Parameters in Management Agent Configuration");
			}
			else
			{
                //Mandatory config Parameters

                //fullImportFile - is the Full Import LDIF file that is written to and presented to ILM.
				fullImportFile = configParameters["Full Import File"].Value.ToString();
                //baseQuery - is the SQL query used to grab data from the sql database.
				baseQuery = configParameters["Base Query"].Value.ToString();
                //db - is the SQL Database to connect too.
				db = configParameters["SQL Database"].Value.ToString();

                //Optional config Parameters
				foreach (ConfigParameter param in configParameters)
				{
                    if (traceLog.TraceEnabled())
                    {
                        traceLog.WriteLine("Parameter: " + param.Name.ToString() + " Value: " + configParameters[param.Name].Value.ToString() + " " + DateTime.Now.ToString());
                    }
					if (param.Name == "Object Class Value")
					{
                        //objectClassValue - Use this if you want to specify the objectClass Value in the LDIF File.
                        //Example.  set the value to person if you want all objects to be of type person.
                        //If this value is not set, then the code will default to "PERSON" for all records.
						objectClassValue = configParameters[param.Name].Value.ToString();	
					}
					if (param.Name == "Object Class Column/Index")
					{
                        //objectClassAttribute - Use this if you want to specify a column name to determine the object type for each object.
                        //Example. Column ObjectType = GROUP for one record and ObjectType = USER for the other record.
                        //If this value is not set, then the code will default to "PERSON" for all records.
						objectClassAttribute = configParameters[param.Name].Value.ToString();	
					}
                    if (param.Name == "Encoding")
                    {
                        //strEncoding - Use this to change the encoding type used to create the ldif file
                        // This must match the management agent configuration to work correctly.
                        string strEncoding = configParameters[param.Name].Value.ToString();
                        encoding = System.Text.Encoding.GetEncoding(strEncoding);
                    }
                    if (param.Name == "Multivalue Query")
                    {
                        //multiValueQuery - use this to add a multivalue query to read in multivalue tables.
                        multiValueQuery = configParameters[param.Name].Value.ToString();
                    }
                    if (param.Name == "Multivalue Attribute Column")
                    {
                        //multiValueAttributeColumn - multiValueQuery must be set to activate this.
                        //this is the column that specifies the name of the multiValue attribute. For instance for groups
                        //Each record would have "member" populated in this column. Multiple values stored in side this column for each record can 
                        //have values to support many different multiValue attributes.
                        //This works very similar to the default SQL and Oracle management agents.
                        multiValueAttributeColumn = configParameters[param.Name].Value.ToString();
                    }
                    if (param.Name == "Multivalue Value Column")
                    {
                        //multiValueValueColumn - multiValueQuery must be set to activate this.
                        //this is the column that specifies the value of the multiValue attribute. For instance for groups
                        //Each record would have the users ANCHOR value to build the reference. 
                        //This works very similar to the default SQL and Oracle management agents.
                        multiValueValueColumn = configParameters[param.Name].Value.ToString();
                    }
				}

                if (traceLog.TraceEnabled())
                {
                    traceLog.WriteLine("BaseQuery SQLtoDataTable Started: " + DateTime.Now.ToString());
                }
                System.Data.DataTable baseQueryDataTable = null;
				SQLtoDataTable baseQuerySQLtoDataTable = new SQLtoDataTable(baseQuery, server, db, user, pswd);
                baseQueryDataTable = baseQuerySQLtoDataTable.GetDataTable();
                
                if (traceLog.TraceEnabled())
                {
                    traceLog.WriteLine("BaseQuery SQLtoDataTable Completed: " + DateTime.Now.ToString());
                }

                if (!((multiValueQuery == null) || (multiValueQuery == "")))
                {
                    System.Data.DataTable multiValueQueryDataTable = null;

                    if (traceLog.TraceEnabled())
                    {
                        traceLog.WriteLine("MultiValueQuery SQLtoDataTable Started: " + DateTime.Now.ToString());
                    }
                    SQLtoDataTable multiValueQuerySQLtoDataTable = new SQLtoDataTable(multiValueQuery, server, db, user, pswd);
                    multiValueQueryDataTable = multiValueQuerySQLtoDataTable.GetDataTable();

                    if (traceLog.TraceEnabled())
                    {
                        traceLog.WriteLine("MultiValueQuery SQLtoDataTable Completed: " + DateTime.Now.ToString());
                        traceLog.WriteLine("MultiValueDataTableLDIFExporter Started: " + DateTime.Now.ToString());
                    }
                    if (multiValueAttributeColumn == null || multiValueAttributeColumn == "")
                    {
                        throw new UnexpectedDataException("When configuring a MultiValue query the Multivalue Attribute Column config parameter needs to be set.");
                    }
                    if (multiValueValueColumn == null || multiValueValueColumn == "")
                    {
                        throw new UnexpectedDataException("When configuring a MultiValue query the Multivalue Value Column config parameter needs to be set.");
                    }
                    DataTableLDIFExporter dte = new DataTableLDIFExporter(baseQueryDataTable, multiValueQueryDataTable, fullImportFile, types, objectClassAttribute, objectClassValue, multiValueAttributeColumn, multiValueValueColumn, encoding);

                    if (traceLog.TraceEnabled())
                    {
                        traceLog.WriteLine("MultiValueDataTableLDIFExporter Completed: " + DateTime.Now.ToString());
                        traceLog.WriteLine("GenerateFullImportFile Completed: " + DateTime.Now.ToString());
                    }
                    multiValueQueryDataTable.Dispose();
                }
                else
                {
                    if (traceLog.TraceEnabled())
                    {
                        traceLog.WriteLine("BaseDataTableLDIFExporter Started: " + DateTime.Now.ToString());
                    }
                    DataTableLDIFExporter dte = new DataTableLDIFExporter(baseQueryDataTable, fullImportFile, types, objectClassAttribute, objectClassValue, encoding);

                    if (traceLog.TraceEnabled())
                    {
                        traceLog.WriteLine("BaseDataTableLDIFExporter Completed: " + DateTime.Now.ToString());
                        traceLog.WriteLine("GenerateFullImportFile Completed: " + DateTime.Now.ToString());
                    }
                }
                baseQueryDataTable.Dispose();
			}		
		}
	}
}
